package cn.javabb.generator.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.javabb.generator.config.DataSourceConfig;
import cn.javabb.generator.config.IDbQuery;
import cn.javabb.generator.config.rules.DbType;
import cn.javabb.generator.exception.GeneratorException;
import cn.javabb.generator.model.TableInfo;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;

/**
 * @desc:
 * @author: javabb (javabob(a)163.com)
 * @create: 2020/07/11 00:49
 */
public class GenUtil {
    private String baseDir = System.getProperty("user.dir");  // 项目缓存位置

    // 项目模板路径
    public String getBaseDir() {
        return this.baseDir;
    }

    // 项目模板路径
    public String getTplDir() {
        return this.baseDir + "tpl/";
    }

    // 项目模板解压后的路径
    public String getTemplateDir() {
        return this.baseDir + "template/";
    }

    // 项目生成路径
    public String getTempDir() {
        return this.baseDir + "temp/";
    }

    // 项目生成完打包输出路径
    public String getOutputDir() {
        return this.baseDir + "output/";
    }

    public GenUtil(int index) {
        this.baseDir = File.listRoots()[index] + "/javabb-generator/";
    }
    /**
     * 查询数据库所有表信息
     *
     * @return List<TableInfo>
     */
    public static List<TableInfo> getTableList(DataSourceConfig dataSourceConfig) {

        Connection connection = dataSourceConfig.getConn();
        List<TableInfo> tableInfoList = new ArrayList<>();
        DbType dbType = dataSourceConfig.getDbType();
        IDbQuery dbQuery = dataSourceConfig.getDbQuery();
        try {
            String tablesSql = dataSourceConfig.getDbQuery().tablesSql();
            StringBuilder sql = new StringBuilder(tablesSql);
            cn.javabb.generator.model.TableInfo tableInfo;
            try (
                    PreparedStatement preparedStatement = connection.prepareStatement(sql.toString());
                    ResultSet results = preparedStatement.executeQuery();
            ) {
                while (results.next()) {
                    String tableName = results.getString(dbQuery.tableName());
                    if (StrUtil.isNotBlank(tableName)) {
                        tableInfo = new TableInfo();
                        tableInfo.setName(tableName);
                        String commentColumn = dbQuery.tableComment();
                        if (StrUtil.isNotBlank(commentColumn)) {
                            String tableComment = results.getString(commentColumn);
                            tableInfo.setComment(formatComment(tableComment));
                        }
                        tableInfoList.add(tableInfo);
                    }
                }
            }
        } catch (Exception e) {
            throw new GeneratorException("数据库表读取错误:" + e.getMessage());
        }
        return tableInfoList;
    }
    /**
     * 获取生成后的压缩包文件
     *
     * @param path 文件路径
     * @return File
     */
    public File getOutputFile(String path) {
        return new File(getOutputDir(), path);
    }
    /**
     * 获取模板列表
     */
    public List<Map<String, Object>> listTpl() {
        List<Map<String, Object>> list = new ArrayList<>();
        File dir = new File(getTplDir());
        if (!dir.exists() && dir.mkdirs()) return list;
        File[] files = dir.listFiles();
        if (files == null) return list;
        for (File f : files) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", StrUtil.removeSuffix(f.getName(), ".zip"));
            map.put("size", f.length());
            list.add(map);
        }
        return list;
    }
    /**
     * 格式化数据库注释内容
     */
    public static String formatComment(String comment) {
        return StrUtil.isBlank(comment) ? "" : comment.replaceAll("\r\n", "\t");
    }

    /**
     * 上传模板
     */
    public boolean upload(MultipartFile file) {
        String name = file.getOriginalFilename();
        if (name == null) return false;
        File f = new File(getTplDir(), name);
        if (!f.getParentFile().exists() && !f.getParentFile().mkdirs()) return false;
        try {
            file.transferTo(f);
            FileUtil.del(new File(getTemplateDir(), name));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 获取历史生成记录
     */
    public List<Map<String, Object>> history() {
        List<Map<String, Object>> list = new ArrayList<>();
        File dir = new File(getOutputDir());
        if (!dir.exists() && !dir.mkdirs()) return list;
        File[] files = dir.listFiles();
        if (files == null) return list;
        for (File file : files) {
            File[] fs = file.listFiles();
            if (fs != null && fs.length > 0) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", file.getName());
                map.put("name", StrUtil.removeSuffix(fs[0].getName(), ".zip"));
                map.put("updateTime", fs[0].lastModified());  // 最后修改时间
                list.add(map);
            }
        }
        return list;
    }
    public static <T> T jsonParseObject(String json, Class<T> clazz) {
        if (json != null && !json.trim().isEmpty()) {
            try {
                com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
                return mapper.readValue(json, clazz);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
